With package.json "exports" resolve paths deeply with conditional rules #3993
Description
Details
I am trying to use the exports in my package.json to deeply resolve module paths on top of a base path.
Essentially I have this folder structure:
./my-pkg
└── dist
└── cjs
├── foo
│ ├── bar
│ │ └── index.js
│ └── index.js
└── index.js
And I would like node to be able to resolve the paths above as if they were /
console.log(require('my-pkg')) // my-pkg/dist/cjs/index.js
console.log(require('my-pkg/foo')) // my-pkg/dist/cjs/foo/index.js
console.log(require('my-pkg/foo/bar')) // my-pkg/dist/cjs/foo/bar/index.jsThe basic implementation of exports works for resolving the top level files (except the types keyword isn't being picked up by TypeScript 4.7, but that's another battle for another day):
{
"exports": {
".": {
"types": "./dist/types/index.d.ts",
"import": "./dist/esm/index.js",
"require": "./dist/cjs/index.js"
}
},
...
}This allows me to import the following without issue
console.log(require('my-pkg')) // my-pkg/dist/cjs/index.jsIn the Node documentation it describes using * to add conditional resolution:
{
".": {
"types": "./dist/types/index.d.ts",
"import": "./dist/esm/index.js",
"require": "./dist/cjs/index.js"
},
"./*": {
"types": "./dist/types/*/index.d.ts",
"import": "./dist/esm/*/index.js",
"require": "./dist/cjs/*/index.js"
}
},console.log(require('my-pkg')) // works
console.log(require('my-pkg/foo')) // works
console.log(require('my-pkg/foo/bar')) // does not workThis doesn't allow paths nested beyond ./*/. I have experimented with glob patterns like below but had no luck
{
".": {
"types": "./dist/types/index.d.ts",
"import": "./dist/esm/index.js",
"require": "./dist/cjs/index.js"
},
"./**/*": {
"types": "./dist/types/**/*",
"import": "./dist/esm/**/*",
"require": "./dist/cjs/**/*"
}
},I could explicitly add each nested path into exports manually but I would much prefer deep folder/file resolution be handled by node directly.
Any idea what I need to do to get this working?
Node.js version
Not applicable.
Example code
No response
Operating system
All
Scope
Module resolution
Module and version
Not applicable.
Activity
gabzim commentedon Sep 24, 2023
Any help with this? having the same issue
ljharb commentedon Sep 24, 2023
There is no solution besides doing it manually, for each level of nesting, i believe.
alshdavid commentedon Sep 29, 2023
This (mostly) works:
{ "name": "pkg", "exports": { "./": { "import": "./import/index.js", "require": "./require/index.js" }, "./*": { "import": "./import/*", "require": ["./require/*", "./require/*.js", "./require/*/index.js"] } } }So from a CJS context:
And from a MJS context:
However Node accepts but only resolves the first item in an Array when supplied as a subpattern export.
I have raised a bug report to hopefully change that nodejs/node#49945
If that is updated, then the package.json config above will work as expected for nested patterns.
alshdavid commentedon Sep 29, 2023
looks like there is a discussion on this here: nodejs/node#37928
github-actions commentedon May 7, 2024
It seems there has been no activity on this issue for a while, and it is being closed in 30 days. If you believe this issue should remain open, please leave a comment.
If you need further assistance or have questions, you can also search for similar issues on Stack Overflow.
Make sure to look at the README file for the most updated links.
github-actions commentedon Jun 7, 2024
It seems there has been no activity on this issue for a while, and it is being closed. If you believe this issue should remain open, please leave a comment.
If you need further assistance or have questions, you can also search for similar issues on Stack Overflow.
Make sure to look at the README file for the most updated links.